package com.ruicar.afs.cloud.apply.pre.smallprogram.controller;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruicar.afs.cloud.apply.business.service.ApplySmsSendService;
import com.ruicar.afs.cloud.apply.common.condition.SendMessageCondition;
import com.ruicar.afs.cloud.apply.common.entity.ApplyCustBaseInfo;
import com.ruicar.afs.cloud.apply.common.entity.PreApproveInfo;
import com.ruicar.afs.cloud.apply.pre.approve.service.PreApproveService;
import com.ruicar.afs.cloud.apply.pre.loan.condition.ApplyAppSignAgreeMentCondition;
import com.ruicar.afs.cloud.apply.pre.loan.service.ApplyAppService;
import com.ruicar.afs.cloud.apply.pre.loan.service.ApplyCustBaseInfoService;
import com.ruicar.afs.cloud.apply.pre.smallprogram.condition.ChangeBankInfoCondition;
import com.ruicar.afs.cloud.apply.pre.smallprogram.condition.TencentCloudNuclearBodyCondition;
import com.ruicar.afs.cloud.apply.pre.smallprogram.dto.ChangeBankInfoDTO;
import com.ruicar.afs.cloud.apply.pre.smallprogram.service.ApplySmallProgramService;
import com.ruicar.afs.cloud.bizcommon.cfca.dto.CfCaSignatureDto;
import com.ruicar.afs.cloud.common.core.security.util.AfsPublicTokenUtil;
import com.ruicar.afs.cloud.common.core.util.IResponse;
import com.ruicar.afs.cloud.image.entity.ComAttachmentFile;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static com.ruicar.afs.cloud.apply.common.utils.ApplyConstants.*;

/**
 * description: 小程序
 * @date: 2020/8/19 14:28
 * @author mingzhi.li
 */
@Slf4j
@RestController
@RequestMapping("/smallprogram")
@AllArgsConstructor
public class ApplySmallProgramController {

    private final PreApproveService preApproveService;
    private final ApplySmsSendService applySmsSendService;
    private final StringRedisTemplate stringRedisTemplate;
    private final ApplyCustBaseInfoService applyCustBaseInfoService;
    private final ApplyAppService applyAppService;
    private final ApplySmallProgramService applySmallProgramService;

    /**
     * 人脸核身SaaS化服务，调用接口获取BizToken
     *
     * @param condition
     * @return
     */
    @PostMapping("/getBizToken")
    @ApiOperation(value = "获取人脸核身token")
    public IResponse getBizToken(@RequestBody TencentCloudNuclearBodyCondition condition) {
        if(StrUtil.isBlank(condition.getVerCode())){
            return IResponse.fail("验证码不能为空");
        }
        if(StrUtil.isBlank(condition.getSignScene())){
            return IResponse.fail("签约场景不能为空");
        }
        if(MESSAGE_TYPE_ZERO.equals(condition.getSignScene())){
            IResponse iResponse = applySmallProgramService.signScenePre(condition);
            if(CODE_SUCCESS.equals(iResponse.getCode())){
                return IResponse.success(iResponse.getData());
            }else{
                return IResponse.fail(iResponse.getMsg());
            }
        }else if(CHANGE_BANK_INFO.equals(condition.getSignScene())){
            IResponse iResponse = applySmallProgramService.signSceneChangeBankInfo(condition);
            if(CODE_SUCCESS.equals(iResponse.getCode())){
                return IResponse.success(iResponse.getData());
            }else{
                return IResponse.fail(iResponse.getMsg());
            }
        }else{
            IResponse iResponse = applySmallProgramService.signSceneRole(condition);
            if(CODE_SUCCESS.equals(iResponse.getCode())){
                return IResponse.success(iResponse.getData());
            }else{
                return IResponse.fail(iResponse.getMsg());
            }
        }
    }

    /**
     * 小程序获取预审信息或客户详情会贷后银行卡变更信息
     *
     * @param condition
     * @return
     */
    @PostMapping("/getTrialBatchInfo")
    @ApiOperation(value = "小程序获取预审信息或客户详情会贷后银行卡变更信息")
    public IResponse getTrialBatchInfo(@RequestBody TencentCloudNuclearBodyCondition condition) {
        if(StrUtil.isBlank(condition.getIdCard())){
            return IResponse.fail("证件号码不能为空");
        }
        if(StrUtil.isBlank(condition.getName())){
            return IResponse.fail("客户姓名不能为空");
        }
        if(StrUtil.isBlank(condition.getPhone())){
            return IResponse.fail("手机号码不能为空");
        }
        if(StrUtil.isBlank(condition.getSignScene())){
            return IResponse.fail("签约场景不能为空");
        }
        if(MESSAGE_TYPE_ZERO.equals(condition.getSignScene())){
            if(condition.getPreId()==null){
                return IResponse.fail("预审客户id不能为空！");
            }
        }else if(CHANGE_BANK_INFO.equals(condition.getSignScene())){
            if(StrUtil.isBlank(condition.getCaseNo())){
                return IResponse.fail("贷后银行卡变更编号不能为空！");
            }
            if(condition.getCaseId()==null){
                return IResponse.fail("贷后银行卡变更id不能为空！");
            }
        }else{
            if(condition.getCustId()==null){
                return IResponse.fail("客户id不能为空！");
            }
            if(StrUtil.isBlank(condition.getApplyNo())){
                return IResponse.fail("申请编号不能为空！");
            }
        }
        if(MESSAGE_TYPE_ZERO.equals(condition.getSignScene())){
            log.info("根据证件号码、业务类型获取预审批信息："+condition.getName());
            PreApproveInfo info = preApproveService.getOne(Wrappers.<PreApproveInfo>query().lambda()
                    .eq(PreApproveInfo::getId, condition.getPreId()));
            if(info ==null){
                return IResponse.fail("预审客户信息不存在");
            }
            if(!condition.getPhone().equals(info.getTelPhone())){
                return IResponse.fail("手机号与预审录入不一致");
            }
            if(!condition.getIdCard().equals(info.getCertNo())){
                return IResponse.fail("证件号码与预审录入不一致");
            }
            if(!condition.getName().equals(info.getCustName())){
                return IResponse.fail("客户姓名与预审录入不一致");
            }
            log.info("短信逻辑处理开始："+condition.getName());
            SendMessageCondition messageCondition = new SendMessageCondition();
            messageCondition.setMessageType(MESSAGE_TYPE_ONE);
            messageCondition.setUsageScenarios(USAGESCENARIOS_TYPE_ZERO);
            messageCondition.setCertNo(condition.getIdCard());
            messageCondition.setBusinessType(condition.getBusinessType());
            messageCondition.setPreId(condition.getPreId());
            IResponse verCode= applySmsSendService.send(messageCondition);
            log.info(condition.getName()+"短信验证码========>"+verCode);
            return IResponse.success(info.getId().toString());
        }else if(CHANGE_BANK_INFO.equals(condition.getSignScene())){
            //贷后银行卡变更信息
            ChangeBankInfoDTO info =applySmallProgramService.getBankCardInfo(condition.getCaseNo());
            if(info ==null){
                return IResponse.fail("变更客户信息不存在");
            }
            if(!condition.getPhone().equals(info.getPhone())){
                return IResponse.fail("手机号录入不一致");
            }
            if(!condition.getIdCard().equals(info.getCertNo())){
                return IResponse.fail("证件号码录入不一致");
            }
            if(!condition.getName().equals(info.getCustName())){
                return IResponse.fail("客户姓名录入不一致");
            }
            log.info("短信逻辑处理开始："+condition.getName());
            SendMessageCondition messageCondition = new SendMessageCondition();
            messageCondition.setMessageType(MESSAGE_TYPE_THREE);
            messageCondition.setUsageScenarios(USAGESCENARIOS_TYPE_THREE);
            messageCondition.setCertNo(condition.getIdCard());
            messageCondition.setCaseNo(condition.getCaseNo());
            messageCondition.setCaseName(info.getCustName());
            messageCondition.setTelPhone(info.getPhone());
            messageCondition.setCaseId(condition.getCaseId());
            IResponse verCode= applySmsSendService.send(messageCondition);
            log.info(condition.getName()+"短信验证码========>"+verCode);
            return IResponse.success(info.getCaseNo());
        }else{
            log.info("根据证件号码、业务类型获取客户信息："+condition.getName());
            ApplyCustBaseInfo custBaseInfo = applyCustBaseInfoService.getOne(Wrappers.<ApplyCustBaseInfo>query().lambda()
                    .eq(ApplyCustBaseInfo::getId, condition.getCustId()));
            if(custBaseInfo ==null){
                return IResponse.fail("客户信息不存在！");
            }
            if(!condition.getPhone().equals(custBaseInfo.getTelPhone())){
                return IResponse.fail("手机号与客户信息录入不一致");
            }
            if(!condition.getIdCard().equals(custBaseInfo.getCertNo())){
                return IResponse.fail("证件号码与预审录入不一致");
            }
            if(!condition.getName().equals(custBaseInfo.getCustName())){
                return IResponse.fail("客户姓名与预审录入不一致");
            }
            log.info("短信逻辑处理开始："+condition.getName());
            SendMessageCondition messageCondition = new SendMessageCondition();
            messageCondition.setMessageType(MESSAGE_TYPE_ONE);
            messageCondition.setUsageScenarios(USAGESCENARIOS_TYPE_ONE);
            messageCondition.setCertNo(condition.getIdCard());
            messageCondition.setApplyNo(condition.getApplyNo());
            messageCondition.setCustId(condition.getCustId());
            IResponse verCode= applySmsSendService.send(messageCondition);
            log.info(condition.getName()+"短信验证码========>"+verCode);
            return IResponse.success(custBaseInfo.getId().toString());
        }
    }

    /**
     * 小程序征信授权书签字
     *
     * @param condition
     * @return
     */
    @PostMapping("/signSmallProgram")
    @ApiOperation(value = "小程序征信授权书签字")
    public IResponse signSmallProgram(@RequestBody TencentCloudNuclearBodyCondition condition) {
        if(condition.getFileId() ==null && condition.getFileId().length==0){
            return IResponse.fail("文件id不能为空");
        }
        if(condition.getCustId() ==null){
            return IResponse.fail("客户id不能为空");
        }
        if(condition.getFile() ==null && condition.getFile().length==0){
            return IResponse.fail("签约图片不能为空");
        }
        if(StrUtil.isBlank(condition.getSignScene())){
            return IResponse.fail("签约场景不能为空");
        }

        if(StrUtil.isBlank(condition.getApplyNo())){
            return IResponse.fail("附件编号不能为空");
        }
        log.info("签约文件合成开始");
        CfCaSignatureDto dto = new CfCaSignatureDto();
        dto.setFile(condition.getFile());
        dto.setFileId(condition.getFileId());
        dto.setCustId(condition.getCustId());
        dto.setSignScene(condition.getSignScene());
        dto.setApplyNo(condition.getApplyNo());
        dto.setRotationAngle(condition.getRotationAngle());
        IResponse iResponse = applyAppService.electronicSignature(dto);
        if(!Boolean.TRUE.equals(iResponse.getData())){
            return IResponse.fail("签约失败");
        }else{
            if(MESSAGE_TYPE_ZERO.equals(dto.getSignScene())){
                //小程序电子签名完成后更新签约状态
                PreApproveInfo info = preApproveService.getOne(Wrappers.<PreApproveInfo>query().lambda().eq(PreApproveInfo::getId, dto.getCustId()));
                if(info !=null){
                    info.setSignResult(YES);
                    preApproveService.updateById(info);
                }
                ApplyAppSignAgreeMentCondition mentCondition = new ApplyAppSignAgreeMentCondition();
                mentCondition.setPreId(info.getId());
                mentCondition.setSignScene(MESSAGE_TYPE_ZERO);
                List<ComAttachmentFile> fileList = applyAppService.getPreFileList(mentCondition);
                return IResponse.success(fileList);
            }else{
                ApplyAppSignAgreeMentCondition mentCondition = new ApplyAppSignAgreeMentCondition();
                mentCondition.setCustId(condition.getCustId());
                mentCondition.setApplyNo(condition.getApplyNo());
                List<ComAttachmentFile> fileList = applyAppService.getPreFileList(mentCondition);
                return IResponse.success(fileList);
            }
        }
    }

    /**
     * 小程序贷后银行卡签约
     *
     * @param condition
     * @return
     */
    @PostMapping("/signSmallProgramBankInfo")
    @ApiOperation(value = "小程序贷后银行卡变更签约")
    public IResponse signSmallProgramBankInfo(@RequestBody TencentCloudNuclearBodyCondition condition) {
        if(StrUtil.isBlank(condition.getCaseNo())){
            return IResponse.fail("贷后银行卡变更编号不能为空！");
        }
        if(condition.getCaseId()==null){
            return IResponse.fail("贷后银行卡变更id不能为空！");
        }
        if(condition.getFile() ==null && condition.getFile().length==0){
            return IResponse.fail("签约图片不能为空");
        }
        if(StrUtil.isBlank(condition.getSignScene())){
            return IResponse.fail("签约场景不能为空");
        }
        log.info("签约文件合成开始");
        CfCaSignatureDto dto = new CfCaSignatureDto();
        dto.setCaseNo(condition.getCaseNo());
        dto.setFile(condition.getFile());
        dto.setRotationAngle(condition.getRotationAngle());
        IResponse iResponse = applyAppService.electronicBankInfo(dto);
        if(CODE_SUCCESS.equals(iResponse.getCode())){
            log.info("新文件："+iResponse.getData());
            List<ComAttachmentFile> fileList = new ArrayList<>();
            fileList.add((ComAttachmentFile) iResponse.getData());
            applySmallProgramService.sendFileList((ComAttachmentFile) iResponse.getData());
            return IResponse.success(fileList);
        }else{
            return IResponse.fail(iResponse.getMsg());
        }
    }

    /**
     * 小程序二维码获取Token
     *
     * @param condition
     * @return
     */
    @PostMapping("/getSmallProgramToken")
    @ApiOperation(value = "小程序二维码获取Token")
    public IResponse getSmallProgramToken(@RequestBody TencentCloudNuclearBodyCondition condition) {
        if(StrUtil.isBlank(condition.getKeyUuId())){
            return IResponse.fail("获取Token密钥不能为空");
        }
        JSONObject json =JSONObject.parseObject(stringRedisTemplate.opsForValue().get(condition.getKeyUuId()));
        if(json==null){
            return IResponse.fail("token已到期!");
        }else{
            Map map = (Map) AfsPublicTokenUtil.getPublicToken();
            String sysToken = (String) map.get("access_token");
            json.put("sysToken",sysToken);
            String signScene = (String) json.get("signScene");
            String caseNo = (String) json.get("caseNo");
            if(CHANGE_BANK_INFO.equals(signScene)){
                //贷后银行卡变更
                ChangeBankInfoDTO dto =applySmallProgramService.getBankCardInfo(caseNo);
                json.put("bankInfo",dto);
            }
        }
        return IResponse.success(json);
    }

    /**
     * 获取小程序二维码
     *
     * @return
     */
    @PostMapping("/getSmallProgramQrCode")
    @ApiOperation(value = "获取小程序二维码")
    public IResponse getSmallProgramQrCode(@RequestBody TencentCloudNuclearBodyCondition condition) {
        if(StrUtil.isBlank(condition.getSignScene())){
            return IResponse.fail("签约场景不能为空！");
        }
        if(MESSAGE_TYPE_ZERO.equals(condition.getSignScene())){
            if(condition.getPreId()==null){
                return IResponse.fail("预审客户id不能为空！");
            }
            PreApproveInfo info = preApproveService.getOne(Wrappers.<PreApproveInfo>query().lambda()
                    .eq(PreApproveInfo::getId, condition.getPreId()));
            if(info ==null){
                return IResponse.fail("预审客户信息不存在");
            }
        }else{
            if(condition.getCustId()==null){
                return IResponse.fail("客户id不能为空！");
            }
            if(StrUtil.isBlank(condition.getApplyNo())){
                return IResponse.fail("申请编号不能为空！");
            }
            ApplyCustBaseInfo custBaseInfo = applyCustBaseInfoService.getOne(Wrappers.<ApplyCustBaseInfo>query().lambda()
                    .eq(ApplyCustBaseInfo::getId, condition.getCustId()));
            if(custBaseInfo ==null){
                return IResponse.fail("客户信息不存在！");
            }
        }
        Map map = preApproveService.getSmallProgramQrCode(condition);
        return IResponse.success(map);
    }

    /**
     * 获取贷后合同信息银行卡变更信息
     *
     * @param condition
     * @return
     */
    @PostMapping("/getContractRedisInfo")
    @ApiOperation(value = "获取贷后合同信息银行卡变更信息")
    public IResponse getContractRedisInfo(@RequestBody ChangeBankInfoCondition condition){
        if(condition ==null || StrUtil.isBlank(condition.getKeyUuId())){
            return IResponse.fail("签约信息不存在！");
        }
        JSONObject json = new JSONObject();
        json.put("signScene",condition.getSignScene());
        json.put("caseNo",condition.getCaseNo());
        json.put("caseId",condition.getId());
        log.info("redis缓存key："+condition.getKeyUuId());
        stringRedisTemplate.opsForValue().set(condition.getKeyUuId(), json.toJSONString(), 30, TimeUnit.MINUTES);
        return IResponse.success("成功");
    }

    /**
     * 获取人脸识别错误次数回调
     *
     * @param condition
     * @return
     */
    @PostMapping("/getSignFileNumber")
    @ApiOperation(value = "获取人脸识别错误次数回调")
    public IResponse getSignFileNumber(@RequestBody TencentCloudNuclearBodyCondition condition) {
        if(StrUtil.isBlank(condition.getSignScene())){
            return IResponse.fail("签约场景不能为空！");
        }
        if(MESSAGE_TYPE_ZERO.equals(condition.getSignScene())){
            if(condition.getPreId()==null){
                return IResponse.fail("预审客户id不能为空！");
            }
            if(StrUtil.isBlank(condition.getTransactionCode())){
                return IResponse.fail("签约失败或成功交易码不能为空！");
            }
            PreApproveInfo info = preApproveService.getOne(Wrappers.<PreApproveInfo>query().lambda()
                    .eq(PreApproveInfo::getId, condition.getPreId()));
            if(info ==null){
                return IResponse.fail("预审客户信息不存在");
            }
            if(CODE_FAILURE.equals(condition.getTransactionCode())){
                int signFailNumber =  info.getSignFailNumber() == null ? 0 : info.getSignFailNumber();
                info.setSignFailNumber(signFailNumber+1);
            }else{
                info.setSignFailNumber(0);
            }
            preApproveService.updateById(info);
            return IResponse.success(info.getSignFailNumber());
        }else if(CHANGE_BANK_INFO.equals(condition.getSignScene())) {
            //暂不处理
            return IResponse.success(0);
        }else{
            if(condition.getCustId()==null){
                return IResponse.fail("客户id不能为空！");
            }
            if(StrUtil.isBlank(condition.getTransactionCode())){
                return IResponse.fail("签约失败或成功交易码不能为空！");
            }
            ApplyCustBaseInfo info = applyCustBaseInfoService.getOne(Wrappers.<ApplyCustBaseInfo>query().lambda()
                    .eq(ApplyCustBaseInfo::getId, condition.getCustId()));
            if(info ==null){
                return IResponse.fail("客户信息不存在！");
            }
            if(CODE_FAILURE.equals(condition.getTransactionCode())){
                int signFailNumber =  info.getSignFailNumber() == null ? 0 : info.getSignFailNumber();
                info.setSignFailNumber(signFailNumber+1);
            }else{
                info.setSignFailNumber(0);
            }
            applyCustBaseInfoService.updateById(info);
            return IResponse.success(info.getSignFailNumber());
        }
    }

    /**
     * 获取人脸识别错误次数
     *
     * @return
     */
    @PostMapping("/getSignNumber")
    @ApiOperation(value = "获取小程序二维码")
    public IResponse getSignNumber(@RequestBody TencentCloudNuclearBodyCondition condition) {
        if(StrUtil.isBlank(condition.getSignScene())){
            return IResponse.fail("签约场景不能为空！");
        }
        if(MESSAGE_TYPE_ZERO.equals(condition.getSignScene())){
            if(condition.getPreId()==null){
                return IResponse.fail("预审客户id不能为空！");
            }
            PreApproveInfo info = preApproveService.getOne(Wrappers.<PreApproveInfo>query().lambda()
                    .eq(PreApproveInfo::getId, condition.getPreId()));
            if(info ==null){
                return IResponse.fail("预审客户信息不存在");
            }
            return IResponse.success(info.getSignFailNumber());
        }else if(CHANGE_BANK_INFO.equals(condition.getSignScene())) {
            //暂不处理
            return IResponse.success(0);
        }else{
            if(condition.getCustId()==null){
                return IResponse.fail("客户id不能为空！");
            }
            ApplyCustBaseInfo info = applyCustBaseInfoService.getOne(Wrappers.<ApplyCustBaseInfo>query().lambda()
                    .eq(ApplyCustBaseInfo::getId, condition.getCustId()));
            if(info ==null){
                return IResponse.fail("客户信息不存在！");
            }
            return IResponse.success(info.getSignFailNumber());
        }
    }

    /**
     * 更新小程序人脸识别状态
     *
     * @return
     */
    @PostMapping("/updatePreFaceResult")
    @ApiOperation(value = "更新小程序人脸识别状态")
    public IResponse updateSignFaceResult(@RequestBody TencentCloudNuclearBodyCondition condition) {
        if (condition.getPreId() == null) {
            return IResponse.fail("预审客户id不能为空！");
        }
        PreApproveInfo info = preApproveService.getOne(Wrappers.<PreApproveInfo>query().lambda()
                .eq(PreApproveInfo::getId, condition.getPreId().toString()));
        if (info == null) {
            return IResponse.fail("预审客户信息不存在");
        }
        info.setFaceResult(YES);
        preApproveService.updateById(info);
        return IResponse.success(true);
    }
}
